﻿using System.Threading;
using AviationSimulator.Factories;

namespace AviationSimulator
{
    class SimulationRunner
    {
        public bool CancelationPendingStatus;

        public void Start(ProgramMode programMode)
        {
            switch (programMode)
            {
                case ProgramMode.Import:
                    SendPackagesFromFile();
                    break;
                case ProgramMode.Manual:
                    SendSinglePackage();
                    break;
                case ProgramMode.Receive:
                    ReceivePackages();
                    break;
                case ProgramMode.MathFunction:
                    SendPackagesFromMathFunctions();
                    break;
            }

        }

        private void SendPackagesFromMathFunctions()
        {
            var mathFunctionMode = ManagerFactory.MathFunctionMode;

            while (!CancelationPendingStatus)
            {
                var package = mathFunctionMode.GeneratePackage();
                ManagerFactory.NetworkManager.SendPackage(package, mathFunctionMode.Address, mathFunctionMode.Port);
            }
        }

        private void ReceivePackages()
        {
            var receiveMode = ManagerFactory.ReceiveMode;

            while (!CancelationPendingStatus)
            {
                var package = ManagerFactory.NetworkManager.ReceivePackage(receiveMode.Address, receiveMode.Port);
                package.Number = ManagerFactory.PackageManager.TemporaryPackageStorage.Count;
                ManagerFactory.PackageManager.AddPackageToTempStorage(package);
            }
        }

        public void SetCancelationStatus(bool cancelationPending)
        {
            CancelationPendingStatus = cancelationPending;
        }

        private void SendPackagesFromFile()
        {
            var importMode = ManagerFactory.ImportMode;
            var packages = ManagerFactory.PackageManager.GetPackagesFromFile(importMode.FilePath);

            for (int index = 0; index < packages.Count; index++)
            {
                if (CancelationPendingStatus)
                {
                    return;
                }

                ManagerFactory.NetworkManager.SendPackage(packages[index], importMode.Address, importMode.Port);
                Thread.Sleep(importMode.Period);

                if (importMode.SendPeriodically)
                {
                    if (index == (packages.Count - 1))
                        index = 0;
                }
            }
        }

        private void SendSinglePackage()
        {
            var manualMode = ManagerFactory.ManualMode;

            while (!CancelationPendingStatus)
            {
                ManagerFactory.NetworkManager.SendPackage(manualMode.Package, manualMode.Address, manualMode.Port);
                Thread.Sleep(manualMode.Period);
            }
        }
    }
}
